function decimalMaskKeyPress(e) {
    if(e.key > 47 && e.key < 58){
        var o, s, l = (s = ((o = this).value.replace(/^-?0+/g, "") + String.fromCharCode(e.key)).replace(/\D/g, "")).length, n;
        var oldValue = o.value;
        var negativeChar = "";
        if (oldValue.charAt(0) == '-') negativeChar = "-";
        if(o.maxLength + 1 && l >= o.maxLength) return false;
        l <= (n = o.c) && (s = new Array(n - l + 2).join("0") + s);
        for(var i = (l = (s = s.split("")).length) - n; (i -= 3) > 0; s[i - 1] += o.dig);
        n && n < l && (s[l - ++n] += o.dec);
        o.value = negativeChar + s.join("");
    } else if(this.neg && e.key == 45){
        var o = this;
        var oldValue = o.value;
        if (oldValue.charAt(0) != '-') {
            o.value = "-" + oldValue;
        }
    }
    e.key > 30 && e.preventDefault();
}

function decimalMaskBlur(e) {
    var o, s, l = (s = ((o = this).value.replace(/^-?0+/g, "") + String.fromCharCode(e.key)).replace(/\D/g, "")).length, n;
    if(o.value == '') return false;
    var oldValue = o.value;
    var negativeChar = "";
    if (oldValue.charAt(0) == '-') negativeChar = "-";
    if(o.maxLength + 1 && l >= o.maxLength) return false;
    l <= (n = o.c) && (s = new Array(n - l + 2).join("0") + s);
    for(var i = (l = (s = s.split("")).length) - n; (i -= 3) > 0; s[i - 1] += o.dig);
    n && n < l && (s[l - ++n] += o.dec);
    o.value = s.join("");
    o.value = negativeChar + s.join("");
}

function applyDecimalMask(obj, dec, digSep, decSep, neg){
    obj.c = !isNaN(dec) ? Math.abs(dec) : 2;
    obj.dec = typeof decSep != "string" ? "," : decSep;
    obj.dig = typeof digSep != "string" ? "." : digSep;
    obj.neg = neg;
    addEvent(obj, "keypress", decimalMaskKeyPress);
    addEvent(obj, "blur", decimalMaskBlur);
    addEvent(obj, "keydown", fixDecimalMaskHandler);
    addEvent(obj, "keyup", fixDecimalMaskHandler);
    fixDecimalMask(obj, true);
}


function applyDecimalMaskByTagAndClassName(tag, className, dec, digSep, decSep, neg) {
  var elements  = getElementsByTagAndClassName(tag, className);
  for (i=0; i<elements.length; i++) {
    applyDecimalMask(elements[i], dec, digSep, decSep, neg);
  }
}


function fixDecimalMaskHandler(evt) {
  fixDecimalMask(this);
}

function fixDecimalMask(obj, forceFormat) {
  var str = new String(obj.value);
  var d = obj.dec;
  var m = obj.dig;
  var c = obj.c;
  if (!str || str == "") {
    return;
  }
  var sign =  "";

  var limpo = "";

  if (forceFormat) {
    if (str.indexOf(d) == -1) {
      oldc = 0;
    } else {
      oldc = str.length - str.lastIndexOf(d) - 1;
    }
    for (var i=0; i < c - oldc; i++) {
      str = str + "0";
    }
  }
  
  for (var i=0; i<str.length; i++) {
    var ch = str.charAt(i);
    if (!isNaN(ch)) {
      limpo = limpo + ch;
    } else if (ch == "-" && limpo.length == 0) {
      sign = "-";
    }
  }

  if (limpo.length < 1) {
    this.value = sign;
    return;
  }

  var integ;
  var frac;
  if (forceFormat && oldc > c) {
    integ = limpo.substring(0,limpo.length - oldc);
    frac = limpo.substring(limpo.length - oldc, limpo.length);
    frac = Math.round(frac / Math.pow(10, oldc -c));
  } else {
    integ = limpo.substring(0,limpo.length - c);
    frac = limpo.substring(limpo.length - c, limpo.length);
  }

  if (forceFormat && integ == "") {
    integ = "0";
  }

  var result = "" + d + frac;
  for (var i=1; i<=integ.length; i++) {
    var ch = integ.charAt(integ.length - i);
    if (!isNaN(ch)) {
      result = ch + result;
    }
    if (i!= integ.length && i%3==0) {
      result = m + result;
    }
  }

  obj.value = sign + result;
}

